/*
 * @Description: 工具文件
 */

// import FontFaceObserver from 'fontfaceobserver';

/**
 * @description: 图片文件转字符串
 * @param {Blob|File} file 文件
 * @return {String}
 */
export function getImgStr(file) {
  return new Promise((resolve, reject) => {
    try {
      const reader = new FileReader();
      reader.readAsDataURL(file);
      reader.onload = () => {
        resolve(reader.result);
      };
    } catch (error) {
      reject(error);
    }
  });
}

/**
 * @description: 根据json模板下载字体文件
 * @param {String} str
 * @return {Promise}
 */
export function downFontByJSON(str) {
  const skipFonts = ['arial', 'Microsoft YaHei'];
  const fontFamilies = JSON.parse(str)
    .objects.filter(
      (item) =>
        // 为text 并且不为包含字体
        // eslint-disable-next-line implicit-arrow-linebreak
        item.type.includes('text') && !skipFonts.includes(item.fontFamily)
    )
    .map((item) => item.fontFamily);
  const fontFamiliesAll = fontFamilies.map((fontName) => {
    const font = new FontFaceObserver(fontName);
    return font.load(null, 150000);
  });
  return Promise.all(fontFamiliesAll);
}

/**
 * @description: 选择文件
 * @param {Object} options accept = '', capture = '', multiple = false
 * @return {Promise}
 */
export function selectFiles(options) {
  const createInputFile = ({ accept = '', capture = '', multiple = false }) => {
    const input = document.createElement('input');
    input.type = 'file';
    input.accept = accept;
    input.capture = capture;
    input.multiple = multiple;
    return input;
  };

  return new Promise((resolve) => {
    const input = createInputFile(options);

    input.addEventListener('change', () => resolve(input.files || null));

    setTimeout(() => {
      const event = new MouseEvent('click');
      input.dispatchEvent(event);
    }, 0);
  });
}

/**
 * @description: 前端下载文件
 * @param {String} fileStr
 * @param fileName
 */
export function downFile(fileStr, fileName) {
  const anchorEl = document.createElement('a');
  anchorEl.href = fileStr;
  anchorEl.download = fileName;
  document.body.appendChild(anchorEl); // required for firefox
  anchorEl.click();
  anchorEl.remove();
}

/**
 * @description: 创建图片元素
 * @param {String} str 图片地址或者base64图片
 * @return {Promise} element 图片元素
 */
export function insertImgFile(str) {
  return new Promise((resolve) => {
    const imgEl = document.createElement('img');
    imgEl.src = str;
    // 插入页面
    document.body.appendChild(imgEl);
    imgEl.onload = () => {
      resolve(imgEl);
    };
  });
}


/**
 * @description: 防抖
 * @param {String} fn	源函数, wait	延迟毫秒数
 * @return {Promise} 返回值	目标函数
 */
export function debounce(fn, wait, immediate) {
  let timeout;

  return function () {
    const ctx = this;
    const args = arguments;

    const throttler = function () {
      timeout = null;
      fn.apply(ctx, args);
    };

    if (!immediate) clearTimeout(timeout);
    if (!immediate || !timeout) timeout = setTimeout(throttler, wait);
  };
};


/**
 * @description: 节流
 * @param {String} fn	源函数, wait	延迟毫秒数
 * @return {Promise} 返回值	目标函数
 */
export function throttle(fn, wait) {
  return debounce(fn, wait, true);
};


/* ------------------------------ has ------------------------------ */
const hasOwnProp = Object.prototype.hasOwnProperty;
const has = function (obj, key) {
  return hasOwnProp.call(obj, key);
};
/* ------------------------------ objToStr ------------------------------ */
const ObjToStr = Object.prototype.toString;
const objToStr = function (val) {
  return ObjToStr.call(val);
};
/* ------------------------------ isArgs ------------------------------ */
const isArgs = function (val) {
  return objToStr(val) === '[object Arguments]';
};
/* ------------------------------ isArr ------------------------------ */
const isArr = (function () {
  if (Array.isArray && !false) {
    return Array.isArray;
  } else {
    return function (val) {
      return objToStr(val) === '[object Array]';
    };
  }
})();
/* ------------------------------ isNum ------------------------------ */
const isNum = function (val) {
  return objToStr(val) === '[object Number]';
};
/* ------------------------------ isFn ------------------------------ */
const isFn = function (val) {
  var objStr = objToStr(val);
  return (
    objStr === '[object Function]' ||
    objStr === '[object GeneratorFunction]' ||
    objStr === '[object AsyncFunction]'
  );
};
/* ------------------------------ isArrLike ------------------------------ */
var MAX_ARR_IDX = Math.pow(2, 53) - 1;
const isArrLike = function (val) {
  if (!val) return false;
  var len = val.length;
  return isNum(len) && len >= 0 && len <= MAX_ARR_IDX && !isFn(val);
};
/* ------------------------------ isStr ------------------------------ */
const isStr = function (val) {
  return objToStr(val) === '[object String]';
};
/* ------------------------------ keys ------------------------------ */
const keys = (function () {
  if (Object.keys && !false) {
    return Object.keys;
  } else {
    return function (obj) {
      var ret = [];
      for (var key in obj) {
        if (has(obj, key)) ret.push(key);
      }
      return ret;
    };
  }
}())
/* ------------------------------ isEmpty ------------------------------ */
export const isEmpty = function (val) {
  if (val == null) return true;
  if (isArrLike(val) && (isArr(val) || isStr(val) || isArgs(val))) {
    return val.length === 0;
  }
  return keys(val).length === 0;
};
